import { _decorator, Component, ImageAsset, Node, Sprite, SpriteFrame, tween, UIOpacity, sp, UITransform, Vec3, view } from 'cc';
import { ResourceLoad } from '../service';
import { fadeIn, fadeOut, fitCover, Logger } from 'db://assets/util';
import { BGP_TRANSITION, EASING } from 'db://assets/enum';
const { ccclass, property, menu } = _decorator;



@ccclass('BGPFrame')
@menu('frame/BGP')
export class BGPFrame extends Component {

    #resourceLoader = new ResourceLoad()
    #logger = new Logger('背景帧::BGPFrame')

    @property(Node)
    BGP: Node

    @property(Node)
    blurBGP: Node

    get BGPSP() {
        return this.BGP.getComponent(Sprite)
    }

    get BGPOpacity() {
        return this.BGP.getComponent(UIOpacity)
    }

    get BGPUI() {
        return this.BGP.getComponent(UITransform)
    }

    get blurBGPSP() {
        return this.blurBGP.getComponent(Sprite)
    }

    get transform() {
        return this.getComponent(UITransform)
    }

    protected onLoad(): void {
        this.#logger.debug('#onLoad')
    }

    start() {
        this.#logger.debug('#start')
    }

    async clear() {
        await fadeOut(this.BGP)
        await fadeOut(this.blurBGP)
        return
    }

    async loadBGP(url: string) {
        this.#logger.debug('@加载背景', url)
        const image = await this.#resourceLoader.loadRemote<ImageAsset>(url)
        this.BGPSP.spriteFrame = SpriteFrame.createWithImage(image)
        fitCover(image, this.BGP)
    }

    async initBlurBGP(url: string) {
        this.#logger.debug('@初始化模糊背景', url)
        if (!url) return
        const image = await this.#resourceLoader.loadRemote<ImageAsset>(url)
        this.blurBGPSP.spriteFrame = SpriteFrame.createWithImage(image)
        fitCover(this.blurBGPSP.spriteFrame, this.blurBGP)
        this.blurBGPSP.getComponent(UIOpacity).opacity = 0
        this.blurBGP.position = this.BGP.position
    }

    async transformFrame(content: LDContent.TransformContent) {
        return new Promise(resolve => tween(this.node)
            .to(content.duration, {
                scale: new Vec3(content.scale, content.scale, 0),
                position: new Vec3(content.x, content.y, 0),
            }, { easing: content.easing })
            .call(resolve)
            .start())
    }

    async animeBGP(content: LDContent.BGPContent) {
        this.#logger.debug('@背景动画', content)
        switch (content.transition) {
            case BGP_TRANSITION.TRANSLATE:
                await this.translateBGP(content)
                break;
            case BGP_TRANSITION.FADE:
                await this.fadeBGP(content)
                break;
            default:
                await this.fadeBGP(content)
                break;
        }
    }

    async fadeBGP(content: LDContent.BGPContent) {
        this.BGP.position = Vec3.ZERO
        this.BGPOpacity.opacity = 0
        return await fadeIn(this.BGP)
    }

    async translateBGP(content: LDContent.BGPContent) {
        const range = content.range.split('-')
        if (range.length !== 2) {
            this.#logger.error('@背景动画范围错误', content.range)
            return await this.fadeBGP(content)
        }
        const [start, end] = range.map(v => parseInt(v))
        this.#logger.debug('@背景动画范围', start, end)
        const visible = view.getVisibleSize()
        const bgSize = this.BGPUI.contentSize
        this.#logger.debug('@可见区域', visible, bgSize)

        const limit = bgSize.width - visible.width

        const startPos = new Vec3(limit / 2 - Math.floor(start / 100 * limit), 0, 0)
        const endPos = new Vec3(limit / 2 - Math.floor(end / 100 * limit), 0, 0)

        this.BGP.position = startPos
        this.BGPOpacity.opacity = 255
        return new Promise(resolve => tween(this.BGP)
            .to(1.2, { position: endPos }, { easing: EASING.SMOOTH })
            .call(resolve)
            .start())
    }
}

